module Multi_Control_Unit(
	OP,
	oControl
	);
	input [5:0] OP;
	reg [3:0] S;
	output [19:0] oControl;
	
   assign PCWrite = (~S[0] & ~S[1] & ~S[2] & ~S[3])|(S[0] & ~S[1] & ~S[2] & S[3]);
	assign PCWriteCond = (~S[0] & ~S[1] & ~S[2] & S[3]);
   assign lorD = (S[0] & S[1] & ~S[2] & ~S[3])|(S[0] & ~S[1] & S[2] & ~S[3]);
	assign MemRead = (~S[0] & ~S[1] & ~S[2] & ~S[3])|(S[0] & S[1] & ~S[2] & ~S[3]);
	assign MemWrite = (S[0] & ~S[1] & S[2] & ~S[3]);
	assign IRWrite = (~S[0] & ~S[1] & ~S[2] & ~S[3]);
	assign MemtoReg = (~S[0] & ~S[1] & S[2] & ~S[3]);
   assign PCSource1 = (S[0] & ~S[1] & ~S[2] & S[3]);
	assign PCSource0 = (~S[0] & ~S[1] & ~S[2] & S[3]);
	assign ALUOP1 = (~S[0] & S[1] & S[2] & ~S[3]);
	assign ALUOP0 = (~S[0] & ~S[1] & ~S[2] & S[3]);
	assign ALUSrcB1 = (S[0] & ~S[1] & ~S[2] & ~S[3])|(~S[0] & S[1] & ~S[2] & ~S[3]);
	assign ALUSrcB0 = (~S[0] & ~S[1] & ~S[2] & ~S[3])|(S[0] & ~S[1] & ~S[2] & ~S[3]);
	assign ALUSrcA = (~S[0] & S[1] & ~S[2] & ~S[3])|(~S[0] & S[1] & S[2] & ~S[3])|(~S[0] & ~S[1] & ~S[2] & S[3]);
	assign RegWrite = (~S[0] & ~S[1] & S[2] & ~S[3])|(S[0] & S[1] & S[2] & ~S[3]);
	assign RegDst = (S[0] & S[1] & S[2] & ~S[3]);
	assign NS3 = (S[0] & ~S[1] & ~S[2] & ~S[3] & ~OP[0] & OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & ~OP[5])|
	             (S[0] & ~S[1] & ~S[2] & ~S[3] & ~OP[0] & ~OP[1] & OP[2] & ~OP[3] & ~OP[4] & ~OP[5]);
	assign NS2 = (S[0] & S[1] & ~S[2] & ~S[3])|(~S[0] & S[1] & S[2] & ~S[3])|
	             (S[0] & ~S[1] & ~S[2] & ~S[3] & ~OP[0] & ~OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & ~OP[5])|
                (~S[0] & S[1] & ~S[2] & ~S[3] & OP[0] & OP[1] & ~OP[2] & OP[3] & ~OP[4] & OP[5]);
	assign NS1 = (~S[0] & S[1] & S[2] & ~S[3])|(S[0] & ~S[1] & ~S[2] & ~S[3] & ~OP[0] & ~OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & ~OP[5])|
	             (S[0] & ~S[1] & ~S[2] & ~S[3] & OP[0] & OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & OP[5])|
					 (S[0] & ~S[1] & ~S[2] & ~S[3] & OP[0] & OP[1] & ~OP[2] & OP[3] & ~OP[4] & OP[5])|
					 (~S[0] & S[1] & ~S[2] & ~S[3] & OP[0] & OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & OP[5]);
	assign NS0 = (~S[0] & ~S[1] & ~S[2] & ~S[3])|(~S[0] & S[1] & S[2] & ~S[3])|
	             (S[0] & ~S[1] & ~S[2] & ~S[3] & ~OP[0] & OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & ~OP[5])|
					 (~S[0] & S[1] & ~S[2] & ~S[3] & OP[0] & OP[1] & ~OP[2] & OP[3] & ~OP[4] & OP[5])|
					 (~S[0] & S[1] & ~S[2] & ~S[3] & OP[0] & OP[1] & ~OP[2] & ~OP[3] & ~OP[4] & OP[5]);
					 
   assign oControl[19] = PCWrite;
	assign oControl[18] = PCWriteCond;
	assign oControl[17] = lorD;
	assign oControl[16] = MemRead;
	assign oControl[15] = MemWrite;
	assign oControl[14] = IRWrite;
	assign oControl[13] = MemtoReg;
	assign oControl[12] = PCSource1;
	assign oControl[11] = PCSource0;
	assign oControl[10] = ALUOP1;
	assign oControl[9] = ALUOP0;
	assign oControl[8] = ALUSrcB1;
	assign oControl[7] = ALUSrcB0;
	assign oControl[6] = ALUSrcA;
	assign oControl[5] = RegWrite;
	assign oControl[4] = RegDst;
	assign oControl[3] = NS3;
	assign oControl[2] = NS2;
	assign oControl[1] = NS1;
	assign oControl[0] = NS0;
   
initial begin
S[3:0] = 4'b0000;
end

always @(*)
begin
S[3]=NS3;
S[2]=NS2;
S[1]=NS1;
S[0]=NS0;
end	
endmodule

